package cn.com.kh.hst;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.DigestUtils;
//import org.apache.commons.lang3.StringUtils;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Map;
import java.util.TreeMap;
import java.util.Map.Entry;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import javax.servlet.http.HttpServletRequest;

/**
 * 3DES 加解密
 *
 */
public class ThreeDesUtil {

	/**
	 * 3des对称加密算法
	 */
	private static final String Algorithm = "DESede";

	private static final String UTF8 = "UTF-8";

	/**
	 * 3DES+Base64 加密
	 * 
	 * @param key      秘钥串
	 * @param plainStr
	 * @return
	 */
	public static String encode(String key, String plainStr) {
		try {
			byte[] enk = hex(key); // 秘钥
			byte[] encoded = encryptMode(enk, plainStr.getBytes(UTF8));
			return Base64.encodeBase64String(encoded);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 3DES+Base64 解密
	 * 
	 * @param key     秘钥串
	 * @param destStr
	 * @return
	 */
	public static String decode(String key, String destStr) {
		try {
			byte[] enk = hex(key); // 秘钥
			byte[] destBytes = Base64.decodeBase64(destStr);
			byte[] srcBytes = decryptMode(enk, destBytes);
			if (srcBytes != null) {
				return new String(srcBytes, UTF8);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	// keybyte为加密密钥，长度为24字节
	// src为被加密的数据缓冲区（源）
	private static byte[] encryptMode(byte[] keybyte, byte[] src) {
		try {
			// 生成密钥
			SecretKey deskey = new SecretKeySpec(keybyte, Algorithm);
			// 加密
			Cipher c1 = Cipher.getInstance(Algorithm + "/ECB/PKCS5Padding");
			c1.init(Cipher.ENCRYPT_MODE, deskey);
			return c1.doFinal(src);// 在单一方面的加密或解密
		} catch (Exception e3) {
			e3.printStackTrace();
		}
		return null;

	}

	// keybyte为加密密钥，长度为24字节
	// src为加密后的缓冲区
	private static byte[] decryptMode(byte[] keybyte, byte[] src) {
		try {
			// 生成密钥
			SecretKey deskey = new SecretKeySpec(keybyte, Algorithm);
			// 解密
			Cipher c1 = Cipher.getInstance(Algorithm + "/ECB/PKCS5Padding");
			c1.init(Cipher.DECRYPT_MODE, deskey);
			return c1.doFinal(src);
		} catch (Exception e3) {
			e3.printStackTrace();
		}
		return null;
	}

	/**
	 * 24字节秘钥 MD5后截取前24位
	 * 
	 * @param username
	 * @return
	 */
	private static byte[] hex(String appkey) {
		String f = DigestUtils.md5Hex(appkey);
		byte[] bkeys = new String(f).getBytes();
		byte[] enk = new byte[24];
		for (int i = 0; i < 24; i++) {
			enk[i] = bkeys[i];
		}
		return enk;
	}

	/**
	 * 获取当前网络ip
	 * 
	 * @param request
	 * @return
	 */
	public static String getIpAddr(HttpServletRequest request) {
		String ipAddress = request.getHeader("x-forwarded-for");
		if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
			ipAddress = request.getHeader("Proxy-Client-IP");
		}
		if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
			ipAddress = request.getHeader("WL-Proxy-Client-IP");
		}
		if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
			ipAddress = request.getRemoteAddr();
			if (ipAddress.equals("127.0.0.1") || ipAddress.equals("0:0:0:0:0:0:0:1")) {
				// 根据网卡取本机配置的IP
				InetAddress inet = null;
				try {
					inet = InetAddress.getLocalHost();
				} catch (UnknownHostException e) {
					e.printStackTrace();
				}
				ipAddress = inet.getHostAddress();
			}
		}
		// 对于通过多个代理的情况，第一个IP为客户端真实IP,多个IP按照','分割
		if (ipAddress != null && ipAddress.length() > 15) { // "***.***.***.***".length() = 15
			if (ipAddress.indexOf(",") > 0) {
				ipAddress = ipAddress.substring(0, ipAddress.indexOf(","));
			}
		}
		return ipAddress;
	}

	/**
	 * Map 自然排序
	 * 
	 * @param request
	 * @return
	 */
	public static String sortMap(Map<String, String> param, String client_key, String client_secret) {
		TreeMap<String, String> paramTreeMap = new TreeMap<>(param);
		System.out.println(paramTreeMap);

		String prestr = "";

		for (Entry<String, String> vo : paramTreeMap.entrySet()) {
			vo.getKey();
			vo.getValue();
			prestr = prestr + vo.getKey() + vo.getValue();
		}
		prestr = "client_key" + client_key + prestr + "client_secret" + client_secret;
		return prestr;
	}
	
	/**
	 * Map 拼接 
	 * ad_no=4&full_name=3&secret=5&type=1&user_mobile=2
	 * @param request
	 * @return
	 */
	public static String SplicingMap(Map<String, String> param, String Splicing) {
		TreeMap<String, String> paramTreeMap = new TreeMap<>(param);
        System.out.println(paramTreeMap);
        
        String prestr = "";
        
        for(Entry<String, String> vo : paramTreeMap.entrySet()){
        vo.getKey();
        vo.getValue();
        prestr=prestr+Splicing+vo.getKey()+"="+vo.getValue();
       }
        prestr=prestr.substring(1);
        return prestr;
	}
	

}
